<script setup lang="ts">
import { useWindowSize } from '@vueuse/core'
import { Message } from '@arco-design/web-vue'
import { getEmailCaptcha, getSmsCaptcha, updateUserPassword, updateUserPhone } from '@/apis'
import { useUserStore } from '@/stores'
import { useForm } from '@/hooks'
import * as Regexp from '@/utils/regexp'
import type { Columns, Options, ProForm } from '@/components/ProForm'

const emit = defineEmits<{
  (e: 'change'): void
}>()

const { width } = useWindowSize()
const userStore = useUserStore()
const userInfo = computed(() => userStore.userInfo)

const verifyType = ref()
const title = computed(
  () => `修改${verifyType.value === 'phone' ? '手机号' : verifyType.value === 'password' ? '密码' : '邮箱'}`,
)
const formRef = ref<InstanceType<typeof ProForm>>()

const options: Options = {
  form: {},
  col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 },
  btns: { hide: true },
}

const { form, resetForm } = useForm({
  phone: '',
  email: '',
  captcha: '',
  oldPassword: '',
  newPassword: '',
  rePassword: '',
})

const columns: Columns = [
  {
    label: '手机号',
    field: 'phone',
    type: 'input',
    rules: [
      { required: true, message: '请输入手机号' },
      { match: Regexp.Phone, message: '请输入正确的手机号' },
    ],
    hide: () => {
      return verifyType.value !== 'phone'
    },
  },
  {
    label: '验证码',
    field: 'captcha',
    type: 'input',
    rules: [{ required: true, message: '请输入验证码' }],
    hide: () => {
      return !['phone', 'email'].includes(verifyType.value)
    },
  },
  {
    label: '当前密码',
    field: 'oldPassword',
    type: 'input-password',
    rules: [{ required: true, message: '请输入当前密码' }],
    hide: () => {
      return !userInfo.value.lastPwdModifiedTime
    },
  },
  {
    label: '新密码',
    field: 'newPassword',
    type: 'input-password',
    rules: [
      { required: true, message: '请输入新密码' },
      {
        validator: (value, callback) => {
          if (value === form.oldPassword) {
            callback('新密码不能与当前密码相同')
          } else {
            callback()
          }
        },
      },
    ],
    hide: () => {
      return verifyType.value !== 'password'
    },
  },
  {
    label: '确认新密码',
    field: 'rePassword',
    type: 'input-password',
    props: {
      placeholder: '请再次输入新密码',
    },
    rules: [
      { required: true, message: '请再次输入新密码' },
      {
        validator: (value, callback) => {
          if (value !== form.newPassword) {
            callback('两次输入的密码不一致')
          } else {
            callback()
          }
        },
      },
    ],
    hide: () => {
      return verifyType.value !== 'password'
    },
  },
]

const captchaLoading = ref(false)
const captchaTimer = ref()
const captchaTime = ref(60)
const captchaBtnName = ref('获取验证码')
const captchaDisable = ref(false)
// 重置验证码
const resetCaptcha = () => {
  window.clearInterval(captchaTimer.value)
  captchaTime.value = 60
  captchaBtnName.value = '获取验证码'
  captchaDisable.value = false
}

// 重置
const reset = () => {
  formRef.value?.formRef?.resetFields()
  resetForm()
  resetCaptcha()
}

// 获取验证码
const getCaptcha = async () => {
  // 判断是否输入了手机号
  const isInvalid = await formRef.value?.formRef?.validateField(verifyType.value === 'phone' ? 'phone' : 'email')
  if (isInvalid) {
    return
  }
  // 发送验证码
  try {
    captchaLoading.value = true
    captchaBtnName.value = '发送中...'
    if (verifyType.value === 'phone') {
      await getSmsCaptcha({
        phone: form.phone,
      })
    } else if (verifyType.value === 'email') {
      await getEmailCaptcha({
        email: form.email,
      })
    }
    captchaLoading.value = false
    captchaDisable.value = true
    captchaBtnName.value = `获取验证码(${(captchaTime.value -= 1)}s)`
    Message.success('发送成功')
    captchaTimer.value = window.setInterval(() => {
      captchaTime.value -= 1
      captchaBtnName.value = `获取验证码(${captchaTime.value}s)`
      if (captchaTime.value <= 0) {
        resetCaptcha()
      }
    }, 1000)
  } catch {
    resetCaptcha()
  } finally {
    captchaLoading.value = false
  }
}

// 保存
const save = async () => {
  const isInvalid = await formRef.value?.formRef?.validate()
  if (isInvalid) {
    return false
  }
  try {
    if (verifyType.value === 'phone') {
      await updateUserPhone({
        phone: form.phone,
        captcha: form.captcha,
        oldPassword: form.oldPassword,
      })
    } else if (verifyType.value === 'password') {
      if (form.newPassword !== form.rePassword) {
        Message.error('两次新密码不一致')
        return false
      }
      if (form.newPassword === form.oldPassword) {
        Message.error('新密码与旧密码不能相同')
        return false
      }
      await updateUserPassword({
        oldPassword: form.oldPassword || '',
        newPassword: form.newPassword || '',
      })
    }
    Message.success('修改成功')
    // 修改成功后，重新获取用户信息
    await userStore.refreshUserInfo()
    emit('change')
    return true
  } catch {
    return false
  }
}

const visible = ref(false)
// 打开弹框
const open = (type: string) => {
  verifyType.value = type
  visible.value = true
}

defineExpose({ open })
</script>

<template>
  <a-modal
    v-model:visible="visible" :title="title" :mask-closable="false" :esc-to-close="false"
    :width="width >= 500 ? 500 : '100%'" draggable @before-ok="save" @close="reset"
  >
    <ProForm ref="formRef" v-model="form" :options="options" :columns="columns">
      <template #captcha>
        <a-input v-model="form.captcha" placeholder="请输入验证码" :max-length="6" allow-clear style="flex: 1 1" />
        <a-button
          class="captcha-btn" :loading="captchaLoading" :disabled="captchaDisable" size="large"
          @click="getCaptcha"
        >
          {{ captchaBtnName }}
        </a-button>
      </template>
    </ProForm>
  </a-modal>
</template>

<style lang="less" scoped>
.captcha-btn {
  margin-left: 12px;
  min-width: 98px;
  border-radius: 4px;
}
</style>
